
package at.fhj.itm.generator.postgres;



import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;


/**
 *
 * @author Seuchter
 */
public class VelocityUtil {

    private static String INCLUDE_TEMPLATE = "#parse(\"%s\")\n";

    private static String MACRO_CALL_TEMPLATE = "#%s(%s)";



    public static String createMacroMetaTemplate(List<String> includes,  String macroName, List<String> params)
    {

    	
        StringBuilder sb = new StringBuilder();
        for(String inc : includes)
        {
            sb.append(String.format(INCLUDE_TEMPLATE, inc)).append("\n");
        }
        sb.append("\n");
        StringBuilder arguments = new StringBuilder();
        final char DELIM = ',';

        Iterator<String> paramIter = params.iterator();

        while(paramIter.hasNext())
        {
            String param = paramIter.next();
            arguments.append("$").append(param);
            if(paramIter.hasNext())
            {
                arguments.append(DELIM);
            }
        }
        sb.append(String.format(MACRO_CALL_TEMPLATE,macroName,arguments.toString()));
        return sb.toString();

    }
    
    public static String callVelocityMacro(VelocityEngine engine, 
            List<String> includes, String macroName, Object...params) throws IOException
    {

        List<String> paramNames = extractParamterNames(params);
        String metaTemplate = createMacroMetaTemplate(includes, macroName, paramNames);
        VelocityContext context = createContextFromParams(params);


        StringWriter writer = new StringWriter();

        engine.evaluate(context, writer, "metatemplate-" + macroName, metaTemplate);

        return writer.toString();

    }

    private static List<String> extractParamterNames(Object ... params)
    {
        if((params.length % 2) != 0)
        {
            throw new IllegalArgumentException("Invalid number of parameter name - paramter pairs");
        }
        List<String> paramNames =new ArrayList<String>();

        for(int i  = 0; i < params.length; i+=2)
        {
            paramNames.add(params[i].toString());
        }

        return Collections.unmodifiableList(paramNames);

    }
    private static  VelocityContext createContextFromParams(Object ... params)
    {
        VelocityContext context = new VelocityContext();
        if((params.length % 2) != 0)
        {
            throw new IllegalArgumentException("Invalid number of parameter name - paramter pairs");
        }
        for(int i  = 0; i < params.length; i+=2)
        {
            context.put(params[i].toString(), params[i+1]);
        }
        return context;


    }
}
